
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');



const AssetPlugin = require('./asset-plugin');
const PreloadWebpackPlugin = require('@vue/preload-webpack-plugin');
// const PreloadWebpackPlugin = require('./preload-webpack-plugin');

// 代码分割：
// 1.入口点分割
// 2.动态导入和懒加载
// 3.提取公共代码

const path = require('path');
module.exports = {
    mode: 'development',
    devtool: false,
    entry: {
        main: './src/index.js',
        // 入口点分割
        // 缺点:
        // 如果入口 chunks 之间包含重复的模块(例如：lodash)，那些重复模块都会被引入到各个 bundle 中
        // 不够灵活，并且不能将核心应用程序逻辑进行动态拆分代码
        // page1: "./src/page1.js",
        // page2: "./src/page2.js",
        // page3: "./src/page3.js",
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        //初始（initial）chunk 文件的名称
        filename: '[name].[chunkhash].js',
        //此选项决定了非初始（non-initial）chunk 文件的名称
        chunkFilename: '[name].[chunkhash].js',
    },
    optimization:{
        splitChunks:{
            //all=async(异步)+initial(同步) 表示哪些代码块需要分割，默认是async异步，all等于同步的initial+异步的async
            chunks: 'all',
            //生成chunk的最小体积（以bytes为单位分割出去的代码最小的体积是多少，0就是不限制，默认为30000，约30kb。
            minSize: 0,
            //表示一个模块至少应被minChunks个chunk所包含才能分割。默认为2。
            minChunks: 1,
            // 表示按需加载文件时，并行请求的最大数目。默认为5。
            maxAsyncRequests: 3,
            // 表示加载入口文件时，并行请求的最大数目。默认为3
            maxInitialRequests: 5,
            // 表示拆分出的chunk的名称连接符。默认为~。如chunk~vendors.js
            automaticNameDelimiter: '~',
            cacheGroups: {
                defaultVendors: false,
                default: false,
                commons: {
                    minChunks: 1,
                    // 如果当前 chunk 包含已从主 bundle 中拆分出的模块，则它将被重用。
                    // 而不是生成新的代码块。 这可能会影响 chunk 的结果文件名。
                    reuseExistingChunk: true
                }
            }

            //缓存组可以继承和/或覆盖来自 splitChunks.* 的任何选项
            //缓存组是用来指定代码块分割的条件，哪些模块应该被 提取哪些代码块中
            /* cacheGroups: {
                //默认第三方缓存组
                defaultVendors: {
                    //控制此缓存组选择的模块。省略它会选择所有模块
                    //它可以匹配绝对模块资源路径
                    //如果某个模块资源的绝对路径匹配此正则的话，那么这个模块就可以被提供到此代码块中
                    test: /[\\/]node_modules[\\/]/,
                    priority: -10
                },
                // 默认缓存组
                default: {
                    //指定拆分前模块被 多少个代码块共享 的话才会提取到此代码块中
                    minChunks: 2,
                    //一个模块可以属于多个缓存组 jquery
                    //优化将优先考虑具有更高 priority（优先级）的缓存组
                    //默认组的优先级为负，以允许自定义组获得更高的优先级（自定义组的默认值为 0）
                    priority: -20
                },
                
                // defaultVendors: false,// 禁用默认第三方缓存组
                // default: false,// 禁用默认缓存组
                module2CacheGroup:{
                    //test可以写一个正则表达式用来匹配模块绝对路径
                    //也可以写一个自定义的函数进行匹配，返回true匹配上的，返回false就是没匹配上
                    test(module) {
                        // `module.resource`包含此文件的硬盘上的绝地路径
                        //为了跨平台兼容 ，尽量使用/而非\
                        return (
                            module.resource &&//绝对路径存在
                            module.resource.endsWith('module2.js')
                        );
                    },
                    //指定名字
                    name(module, chunks, cacheGroupKey) {
                        const moduleFileName = module
                            .identifier()
                            .split(/[\\/]/)
                            .reduceRight((item) => item);
                        const allChunksNames = chunks.map((item) => item.name).join('~');
                        return `${cacheGroupKey}-${allChunksNames}-${moduleFileName}`;
                    },
                    priority: -200
                } 
            }, */
        },
        //将 optimization.runtimeChunk 设置为 true 或 'multiple'，会为每个入口添加一个只含有 runtime 的额外 chunk
        //正常来说如果只有page1.js,如果page1.js内容改变了，整个文件都会失效，重新加载.但使用了runtimeChunk就不会，只会改变业务代码改变，不会改变page1运行时代码
        //entrypoint其实就是入口代码块 (page1 page2 page3)
        /* runtimeChunk: {
            name: (entrypoint) => `runtime~${entrypoint.name}`,
        },
        realContentHash: false */
    },
    plugins:[
        new PreloadWebpackPlugin({
            rel: 'prefetch',
            include: 'asyncChunks',
        }),
        // new HtmlWebpackPlugin({
        //     template: './src/index.html'
        // }),
        new HtmlWebpackPlugin({
            template:'./src/index.html',  //模板
            filename:'page1.html', //bundle名称
            chunks:['page1'] //bundle中包含的chunks
        }),
        new HtmlWebpackPlugin({
            template:'./src/index.html',
            filename:'page2.html',
            chunks:['page2']
        }),
        new HtmlWebpackPlugin({
            template:'./src/index.html',
            filename:'page3.html',
            chunks:['page3']
        }),

        new AssetPlugin(),
        new CleanWebpackPlugin({
            cleanOnceBeforeBuildPatterns: ['**/*']
        }),
    ]
}









